﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;

namespace Util
{
    /// <summary>
    /// Keeps references to a list of timers which can be referenced by a key-pair consisting of an owner and a timer name.
    /// </summary>
    public class TimerPool
    {
        private static  Dictionary<Object, List<Timer>> weakRefTimerPool = new Dictionary<Object, List<Timer>>();


        // disable the constructor
        private TimerPool() {

        }


        /**
        /// Retrieves (or creates) a timer with the given name
         *
        /// @param owner
        /// @param timerName the name of the particular timer to retrieve. If the timer does not already exist, it will be
        ///                  created  @return the timer.
         */
        public static  Timer getTimer(Object owner, String timerName) 
        {
            if (!weakRefTimerPool.ContainsKey(owner))
                weakRefTimerPool.Add(owner, new List<Timer>());

            List<Timer> ownerTimers = weakRefTimerPool[owner];

            foreach (Timer timer in ownerTimers) 
            {
                if (timer.getName().Equals(timerName))
                    return timer;
            }

            // there is no timer named 'timerName' yet, so create it
            Timer requestedTimer = new Timer(timerName);
            ownerTimers.Add(requestedTimer);

            return requestedTimer;
        }


        /** Returns the number of currently caches {@code Timer} instances. */
        public static int getNumCachedTimers() 
        {
            int counter = 0;
            foreach (List<Timer> timers in weakRefTimerPool.Values) 
            {
                counter += timers.Count;
            }

            return counter;
        }


        /** Dump all timers */
        public static void dumpAll() 
        {
            showTimesShortTitle();

            foreach (List<Timer> timers in weakRefTimerPool.Values) 
            {
                foreach (Timer timer in timers) 
                {
                    timer.dump();
                }
            }
        }


        /** Shows the timing stats title. */
        private static void showTimesShortTitle() 
        {
            String title = "Timers";
            String titleBar =
                    "# ----------------------------- " + title +
                            "----------------------------------------------------------- ";
            Trace.Write(titleBar);
            Trace.Write("# Name");
            Trace.Write("Count");
            Trace.Write("CurTime");
            Trace.Write("MinTime");
            Trace.Write("MaxTime");
            Trace.Write("AvgTime");
            Trace.WriteLine("TotTime");
            
        }


        /** Resets all timers */
        public static void resetAll() 
        {
            foreach (List<Timer> timers in weakRefTimerPool.Values) 
            {
                foreach (Timer timer in timers) 
                {
                    timer.reset();
                }
            }
        }

    }
}
